#include "vertex_types.fxh"
#include "Samplers.fxh"
#include "globals.fxh"

	// TODO
	float g_SpecularPower = 200;
	float g_SpecularMaterialFactor = 0.8;
	float g_DiffuseMaterialFactor = 0.8;
	float4 g_AmbientLight = {0.1, 0.1, 0.1, 1.0};
	//float4 g_AmbientLight = {0.0, 0.0, 0.0, 1.0};
	float g_Intensity = 1; //Tiene que ser un vector de 4, cada luz tiene su intensidad!

float3 GetOmniContrib(TNORMAL_COLORED_VERTEX_PS IN, int i)
{

	float3 l_LightDir = IN.WorldPosition-g_LightsPosition[i];
	float3 l_NormalizedLightDir = l_LightDir/length(l_LightDir);
	float l_DistAtt = 1 - saturate((length(l_LightDir) - g_LightsStartRangeAttenuation[i])/(g_LightsEndRangeAttenuation[i] - g_LightsStartRangeAttenuation[i]));

	//Specular
    float3 Nn=normalize(IN.WorldNormal);
    float3 Hn=normalize(normalize(g_CameraPosition-IN.WorldPosition)-l_NormalizedLightDir);
    float l_SpecularContrib=pow(saturate(dot(Hn, Nn)), g_SpecularPower);
    float3 l_SpecularLighting=l_SpecularContrib*g_LightsColor[i]*l_DistAtt*g_SpecularMaterialFactor*g_Intensity;

	
	//Diffuse
    float l_DiffuseContrib=saturate(dot(Nn, -l_NormalizedLightDir));
	float3 l_DiffuseLightColor = g_LightsColor[i]*l_DiffuseContrib*l_DistAtt*g_DiffuseMaterialFactor*g_Intensity;

	//Total
    float3 l_TotalColor=l_DiffuseLightColor+l_SpecularLighting;
	return l_TotalColor;

}

float3 GetDirectionalContrib(TNORMAL_COLORED_VERTEX_PS IN, int i)
{
	float3 Nn=normalize(IN.WorldNormal);
    float3 Hn=normalize(normalize(g_CameraPosition-IN.WorldPosition)-g_LightsDirection[i]);
	
	//Specular
    float l_SpecularContrib=pow(saturate(dot(Hn, Nn)), g_SpecularPower);
    float3 l_SpecularLighting=l_SpecularContrib*g_LightsColor[i]*g_SpecularMaterialFactor*g_Intensity;
	//Diffuse
    float l_DiffuseContrib=saturate(dot(Nn, -g_LightsDirection[i]));
	float3 l_DiffuseLightColor = g_LightsColor[0]*l_DiffuseContrib*g_DiffuseMaterialFactor*g_Intensity;

	//Total
    float3 l_TotalColor=l_DiffuseLightColor+l_SpecularLighting;
	return l_TotalColor;
}

float3 GetSpotContrib(TNORMAL_COLORED_VERTEX_PS IN, int i)
{
	float3 l_LightDir = IN.WorldPosition-g_LightsPosition[i];
	float3 l_NormalizedLightDir = l_LightDir/length(l_LightDir);
	float3 Nn=normalize(IN.WorldNormal);
	float l_DistAtt = 1 - saturate((cos(radians(g_LightsAngle[i]/2)) - dot(l_NormalizedLightDir, g_LightsDirection[i]))/(cos(radians(g_LightsAngle[i]/2)) - cos(radians(g_LightsFallOff[i]/2))));
	//Specular
    float3 Hn=normalize(normalize(g_CameraPosition-IN.WorldPosition)-l_NormalizedLightDir);
    float l_SpecularContrib=pow(saturate(dot(Hn, Nn)), g_SpecularPower);
    float3 l_SpecularLighting=l_SpecularContrib*g_LightsColor[i]*l_DistAtt*g_SpecularMaterialFactor*g_Intensity;

	//Diffuse
    float l_DiffuseContrib=saturate(dot(Nn, -l_NormalizedLightDir));
	float3 l_DiffuseLightColor = g_LightsColor[i]*l_DiffuseContrib*l_DistAtt*g_DiffuseMaterialFactor*g_Intensity;

	//Total
    float3 l_TotalColor=l_DiffuseLightColor+l_SpecularLighting;
	return l_TotalColor;
}

TNORMAL_COLORED_VERTEX_PS RenderVS(TNORMAL_COLORED_VERTEX_VS IN)
{
 
    TNORMAL_COLORED_VERTEX_PS OUT = (TNORMAL_COLORED_VERTEX_PS )0;
    OUT.HPosition=mul(float4(IN.Position,1.0),g_WorldViewProjectionMatrix);
    OUT.Color=IN.Color;
    OUT.WorldNormal=mul(IN.Normal,(float3x3) g_WorldMatrix);
    OUT.WorldPosition=mul(float4(IN.Position,1.0), g_WorldMatrix);
    return OUT;
}

float4 RenderPS(TNORMAL_COLORED_VERTEX_PS IN) : COLOR
{
	
	int i = 0;
	float3 l_TotalContrib = float3(0.0, 0.0, 0.0);
	for (i=0; i<MAX_LIGHTS; ++i)
	{
		
		if(g_LightsEnabled[i])
		{
			if(g_LightsType[i] == 0)
			{
				l_TotalContrib = l_TotalContrib + GetOmniContrib(IN, i);
				
			}
			else if(g_LightsType[i] == 1)
			{
				l_TotalContrib = l_TotalContrib + GetDirectionalContrib(IN, i);
			}
			else if(g_LightsType[i] == 2)
			{
				
				l_TotalContrib = l_TotalContrib + GetSpotContrib(IN, i);
			}
		
		}
		
	}
	//return float4(GetOmniContrib(IN, 0), 1.0);
	//return float4(GetSpotContrib(IN, 1), 1.0);
	//return float4(l_TotalContrib, 1.0);
	float4 l_color=IN.Color;
	//return l_color;
	l_TotalContrib = l_TotalContrib + g_AmbientLight;
    return l_color*float4(l_TotalContrib ,1);
}



technique tecColored
{
    pass p0
    {        
        VertexShader =compile vs_3_0 RenderVS();
        PixelShader = compile ps_3_0 RenderPS();
    }
}